package cc.rengu.redp.bizimpl.upmp.controller;


import cc.rengu.igas.bomp.facade.bean.*;
import cc.rengu.igas.bomp.facade.request.MchntBatchImportRequest;
import cc.rengu.igas.bomp.facade.request.OcrRequest;
import cc.rengu.igas.bomp.facade.request.ParamQueryRequest;
import cc.rengu.igas.bomp.facade.response.OcrResponse;
import cc.rengu.igas.bomp.facade.response.ParamQueryResponse;
import cc.rengu.redp.bizimpl.constant.UpmpConstant;
import cc.rengu.redp.bizimpl.enums.*;
import cc.rengu.redp.bizimpl.igas.service.PDstChannelCfgService;
import cc.rengu.redp.bizimpl.igas.vo.OnlineVerificationVO;
import cc.rengu.redp.bizimpl.igas.vo.SettleAcctInfoVO;
import cc.rengu.redp.bizimpl.upmp.bean.ImportExcelColumnAttr;
import cc.rengu.redp.bizimpl.upmp.bean.MchntImportExportInitNew;
import cc.rengu.redp.bizimpl.upmp.common.BusinessContainer;
import cc.rengu.redp.bizimpl.upmp.domain.*;
import cc.rengu.redp.bizimpl.upmp.service.*;
import cc.rengu.redp.bizimpl.upmp.vo.*;
import cc.rengu.redp.bizimpl.utils.*;
import cc.rengu.redp.common.annotation.Log;
import cc.rengu.redp.common.controller.BaseController;
import cc.rengu.redp.common.domain.QueryRequest;
import cc.rengu.redp.common.exception.RedpException;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.*;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author 刘玉亮.LL
 * @since 2021-06-22
 */
@Api(tags = "商户管理:间联商户管理")
@Slf4j
@RestController
@RequestMapping("/admin/mcmp/bMchntBaseInfo")
public class BMchntBaseInfoController extends BaseController {
    @Autowired
    private IUpmpBMchntBaseInfoService bMchntBaseInfoService;
    @Autowired
    private IBizHisService bizHisService;
    @Autowired
    private IUpmpSysParamService upmpSysParamService;
    @Autowired
    private IUpmpBPlatMchntInfoService platMchntInfoService;
    @Autowired
    private PDstChannelCfgService pDstChannelCfgService;
    @Autowired
    private MerGrpInfoService merGrpInfoService;
    @Autowired
    private IndustryInfoService industryInfoService;
    @Autowired
    private RegionInfoService regionInfoService;
    @Autowired
    private IUpmpBMchntLevelInfoService mchntLevelInfoService;
    @Autowired
    private IUpmpOrganizationService upmpOrganizationService;


    /**
     * 商户列表查询
     * @param request
     * @param entity
     * @return
     * @throws RedpException
     */
    @GetMapping("/list")
//    @RequiresPermissions("bMchntBaseInfo:view")
    public Map<String, Object> list(QueryRequest request, UpmpBMchntBaseInfo entity) throws RedpException {
        return getDataTable(this.bMchntBaseInfoService.findByPage(request, entity));
    }

    @Log("获取页面切换数据")
    @GetMapping(value = "/edit-tabs")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "optFlag", value = "操作类型：新增、修改、删除、审核等", required = true, dataType = "String")
    })
    public UpmpBMchntBaseInfo editTabs(UpmpBMchntBaseInfo entity) throws RedpException {
        return bMchntBaseInfoService.editTabs(entity);
    }

    @Log("获取编辑数据")
    @GetMapping(value = "/edit")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "optFlag", value = "操作类型：新增、修改、删除、审核等", required = true, dataType = "String")
    })
    public Map<String, Object> editShow(UpmpBMchntBaseInfo entity) throws RedpException {
        try {
            return bMchntBaseInfoService.editShow(entity);
        } catch (Exception e) {
            String message = "查询失败";
            log.error(message, e);
            throw new RedpException(message);
        }

    }

    @GetMapping()
//    @RequiresPermissions("bMchntBaseInfo:view")
    public Map<String, Object> selectByPage(QueryRequest request, UpmpBMchntBaseInfo entity) throws RedpException {
        return getDataTable(this.bMchntBaseInfoService.selectByPage(request, entity));
    }

    @Log("商户延迟清算管理：新增延迟清算/解除延迟")
    @PutMapping
//    @RequiresPermissions("brand:update")
    public void editOrRelease(UpmpBMchntBaseInfo entity) throws RedpException {
        try {
            this.bMchntBaseInfoService.editOrRelease(entity);
        } catch (Exception e) {
            String message = e.getMessage();
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @GetMapping("isWithDrawal")
    @ApiOperation(value = "是否支持提现")
    public Map<String, Object> isWithDrawal() throws RedpException {
        HashMap<String, Object> result = new HashMap<>();
        ParamQueryRequest req = new ParamQueryRequest();
        UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);
        req.setUserId(user.getId());
        req.setParamKey(ParamQueryKeyEnum.CASH_WITHDRAWAL_FLAG.getType());
        req.setParamType(BusinessContainer.MCMP_TO_BOMP_PARAM_TYPE);
        ParamQueryResponse paramQueryResponse = bMchntBaseInfoService.paramQuery(user.getInstId(), req, bMchntBaseInfoService.genMerOrder(user.getInstId()));
        if (Common.isNotBlank(paramQueryResponse)) {
            List<SysParamBean> sysParamList = paramQueryResponse.getSysParamList();
            if (CollectionUtils.isNotEmpty(sysParamList)) {
                result.put("CASHWITHDRAWALFLAG", sysParamList.get(0).getParamValue());
            }
        }
        return result;
    }

    /**
     * 查商户编码、终端打印商户名称、收单机构代码
     *
     * makeby   --lizk
     * @param instId
     * @return
     */
    @GetMapping("getMchntBaseInfo")
    public List<UpmpBMchntBaseInfo> getByInstId(@RequestParam("instId") String instId){
        return bMchntBaseInfoService.getByInstId(instId);
    }

    @GetMapping("viewHis")
    @ApiOperation(value = "历史数据详情页面跳转")
    public Map<String, Object> hisList(String instId, String mchntNo) throws RedpException {
        HashMap<String, Object> result = new HashMap<>();
        UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);
        result.put("isAdmin", user.isAdmin() ? 1 : 0);
        result.put("instId", instId);
        result.put("mchntNo", mchntNo);
        result.put("status", 1);
        result.put("oprMenuId", bMchntBaseInfoService.getOprMenuId());
        return result;
    }



    @Log("查询历史记录")
    @GetMapping(value = "/listHis")
    @ApiImplicitParam(paramType = "query", name = "manageInstId", value = "原字段orgCode，修改为manageInstId", required = true, dataType = "String")
    public Map<String, Object> findHisByPage(QueryRequest request, BizHis entity) throws RedpException {
        return getDataTable(bizHisService.findByPage(request, entity));
    }

    @Log("查询单条")
    @GetMapping(value = "/getOne")
    @ApiImplicitParam(paramType = "query", name = "id", value = "id主键", required = true, dataType = "String")
    public UpmpBMchntBaseInfo getOne(@NotBlank(message = "{required}") String id) {
        return bMchntBaseInfoService.getById(id);
    }



    @Log("保存")
    @PostMapping(value = "/edit")
//    @RequiresPermissions("bMchntBaseInfo:add")
    public Map<String, Object> editSave(@Valid UpmpBMchntBaseInfo entity) throws RedpException {
        try {
            return this.bMchntBaseInfoService.editSave(entity);
        } catch (Exception e) {
            String message = "处理失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @GetMapping("/editSignInfo")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "mchntNo", value = "商户号", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "optFlag", value = "操作类型：新增、修改、删除、审核等", required = true, dataType = "String")
    })
    public Map<String, Object> signInfoShow(@NotBlank(message = "{required}") String instId, @NotBlank(message = "{required}") String mchntNo, @NotBlank(message = "{required}") String optFlag) throws RedpException {
        try {
            return this.bMchntBaseInfoService.signInfoShow(instId, mchntNo, optFlag);
        } catch (Exception e) {
            String message = "查询失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @PostMapping("/editSignInfo")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "mchntNo", value = "商户号", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "optFlag", value = "操作类型：新增、修改、删除、审核等", required = true, dataType = "String")
    })
    public Map<String, Object> signInfoSave(@Valid UpmpBMchntSignInfo entity) throws RedpException {
        try {
            return this.bMchntBaseInfoService.signInfoSave(entity);
        } catch (Exception e) {
            String message = "处理失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @GetMapping("/editMchntImage")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "mchntNo", value = "商户号", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "optFlag", value = "操作类型：新增、修改、删除、审核等", required = true, dataType = "String")
    })
    public Map<String, Object> editMchntImage(@NotBlank(message = "{required}") String instId, @NotBlank(message = "{required}") String mchntNo, @NotBlank(message = "{required}") String optFlag) throws RedpException {
        try {
            return this.bMchntBaseInfoService.editMchntImage(instId, mchntNo, optFlag);
        } catch (Exception e) {
            String message = "查询失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @PostMapping("/editMchntImage")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "mchntNo", value = "商户号", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "optFlag", value = "操作类型：新增、修改、删除、审核等", required = true, dataType = "String")
    })
    public OperationResult mchntImageSave(@Valid MchntImageManageVO entity) throws RedpException {
        try {
            return this.bMchntBaseInfoService.mchntImageSave(entity);
        } catch (Exception e) {
            String message = "处理失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @GetMapping("/editMchntAcct")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "mchntNo", value = "商户号", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "optFlag", value = "操作类型：新增、修改、删除、审核等", required = true, dataType = "String")
    })
    public Map<String, Object> mchntAcctShow(@NotBlank(message = "{required}") String instId, @NotBlank(message = "{required}") String mchntNo, @NotBlank(message = "{required}") String optFlag) throws RedpException {
        try {
            return this.bMchntBaseInfoService.mchntAcctShow(instId, mchntNo, optFlag);
        } catch (Exception e) {
            String message = "查询失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @PostMapping("/editMchntAcct")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "mchntNo", value = "商户号", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "optFlag", value = "操作类型：新增、修改、删除、审核等", required = true, dataType = "String")
    })
    public OperationResult mchntAcctSave(@Valid MchntSettleInfoManageVO entity) throws RedpException {
        try {
            return this.bMchntBaseInfoService.mchntAcctSave(entity);
        } catch (Exception e) {
            String message = "处理失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @GetMapping("/editMchntProd")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "mchntNo", value = "商户号", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "mchntName", value = "商户名称", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "optFlag", value = "操作类型：新增、修改、删除、审核等", required = true, dataType = "String")
    })
    public Map<String, Object> mchntProdShow(@NotBlank(message = "{required}") String instId, @NotBlank(message = "{required}") String mchntNo, @NotBlank(message = "{required}") String mchntName, @NotBlank(message = "{required}") String optFlag) throws RedpException {
        try {
            return this.bMchntBaseInfoService.mchntProdShow(instId, mchntNo, mchntName, optFlag);
        } catch (Exception e) {
            String message = "查询失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @PostMapping("/editMchntProd")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "mchntNo", value = "商户号", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "optFlag", value = "操作类型：新增、修改、删除、审核等", required = true, dataType = "String")
    })
    public OperationResult mchntProdSave(@Valid MchntProdManagerVO entity) throws RedpException {
        try {
            return this.bMchntBaseInfoService.mchntProdSave(entity);
        } catch (Exception e) {
            String message = "处理失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @GetMapping("/editMchntProdDtl")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "prodCode", value = "产品代码", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "baseProdCode", value = "基础产品代码", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "optFlag", value = "操作类型：新增、修改、删除、审核等", required = true, dataType = "String")
    })
    public Map<String, Object> mchntProdDtlShow(MchntProdUnitedFeeVO entity, String flag) throws RedpException {
        if (Common.isBlank(entity.getProdCode()) || Common.isBlank(entity.getBaseProdCode())) {
            log.error("请求参数[prodCode:{}] 或 [entity.getBaseProdCode():{}]值不能为空！", entity.getProdCode(), entity.getBaseProdCode());
            throw new RedpException("请求参数[prodCode:" + entity.getProdCode() + "] 或 [entity.getBaseProdCode():" + entity.getBaseProdCode() + "]值不能为空！");
        }
        return this.bMchntBaseInfoService.mchntProdDtlShow(entity, flag);

    }

    @PostMapping("/editMchntProdDtl")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "prodCode", value = "产品代码", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "baseProdCode", value = "基础产品代码", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "optFlag", value = "操作类型：新增、修改、删除、审核等", required = true, dataType = "String")
    })
    public OperationResult mchntProdDtlSave(@Valid MchntProdManagerVO entity) throws RedpException {
        try {
            return this.bMchntBaseInfoService.mchntProdDtlSave(entity);
        } catch (Exception e) {
            String message = "处理失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @PostMapping("/acctAuth")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "settleAcctNo", value = "结算账户账号", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "settleAcctName", value = "结算账户名称", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "settleAcctType", value = "结算账户类型", required = true, dataType = "String")
    })
    public OperationResult acctAuth(@Valid SettleAcctInfoVO entity) throws RedpException {
        try {
            return this.bMchntBaseInfoService.acctAuth(entity);
        } catch (Exception e) {
            String message = "处理失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    /**
     * 商户批量导入
     *
     * @param request
     * @return
     */

    //@RequiresPermissions("商户管理:统一支付平台商户管理")
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ResponseBody
    public OperationResult uploadDataFromExcel(@RequestParam(value = "excelFile", required = false) MultipartFile excelFile,
                                               HttpServletRequest request, HttpServletResponse response) throws Exception {
        if (Common.isBlank(excelFile.getOriginalFilename())) {
            return OperationResult.buildFailureResult("请选择文件上传！");
        }
        String instId = request.getParameter("instId");
        UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);
        CommonUtils.validateUserInst(instId, user);
        String defaultInstId = upmpSysParamService.getById(UpmpConstant.IGAS_DEFAULT_INST_ID).getPrimaryValue();
        UpmpSysParam dataDict = upmpSysParamService.findChildrenByPrimaryKeyAndParent("MCHNT_IMPORT_PARAM", BusinessContainer.SYS_IMPORT_EXPORT_PARAM, defaultInstId, null);
        if (Common.isBlank(dataDict)) {
            log.error("解析文件时获取系统参数失败，请联系系统管理员");
            throw new RedpException("解析文件时获取系统参数失败，请联系系统管理员");
        }
        if (Common.isBlank(dataDict.getPrimaryValue())) {
            log.error("解析文件时获取系统参数值失败，请联系系统管理员");
            throw new RedpException("解析文件时获取系统参数值失败，请联系系统管理员");
        }
        ExtPropertyPlaceholderConfigurer extPropertyPlaceholderConfigurer=new ExtPropertyPlaceholderConfigurer();
        Map sysparam = (Map) JSON.parse(dataDict.getPrimaryValue());
        int maxRecords = Common.isBlank(sysparam.get("MAX_RECORDS")) ? Integer.valueOf(extPropertyPlaceholderConfigurer.getProperty("MCHNT_IMPORT_MAX_RECORDS")) : Integer.valueOf(sysparam.get("MAX_RECORDS").toString());
        String path = Common.isBlank(sysparam.get("PATH")) ? extPropertyPlaceholderConfigurer.getProperty("MCHNT_IMPORT_UPLOAD_PATH") : sysparam.get("PATH").toString();
        String errorPath = Common.isBlank(sysparam.get("ERROR_PATH")) ? extPropertyPlaceholderConfigurer.getProperty("MCHNT_IMPORT_ERROR_PATH") : sysparam.get("ERROR_PATH").toString();

        String dbCharset = CommonUtils.getProperties("ValidationMessages.properties", "MCHNT_DB_CHARSET");
        if (Common.isBlank(dbCharset)) {
            log.error("解析文件时获取系统参数[MCHNT_DB_CHARSET]值失败，请联系系统管理员");
            throw new RedpException("解析文件时获取系统参数[MCHNT_DB_CHARSET]值失败，请联系系统管理员");
        }
        DBCharsetEnum dbCharsetEnum;
        if (DBCharsetEnum.SIMPLIFIED_CHINESE_CHINA_AL32UTF8.getType().equals(dbCharset)) {
            dbCharsetEnum = DBCharsetEnum.SIMPLIFIED_CHINESE_CHINA_AL32UTF8;
        } else {
            dbCharsetEnum = DBCharsetEnum.SIMPLIFIED_CHINESE_CHINA_ZHS16GBK;
        }
        String fileName = UUID.randomUUID().toString() + "_" + excelFile.getOriginalFilename();
        String filePath = path + File.separator + DateUtils.formatDate(new Date(), "yyyyMMddHHmmssSSS") + File.separator + fileName;


        int code = 0;
        int realRows = 0;
        List<ImportMchntInfoBean> mchntList = Lists.newArrayList();
        StringBuffer buffErr = new StringBuffer();
        //商户批量导入
        if (fileName.endsWith(".xls")) {    //判断是否为2003excel类型文件
            HSSFWorkbook workbook = null;
            try {
                workbook = new HSSFWorkbook(excelFile.getInputStream());    //2003版本的excel，用.xls结尾.得到工作簿
            } catch (Exception e) {
                log.error("文件读取失败，请联系系统管理员");
                throw new RedpException("文件读取失败，请联系系统管理员");
            }
            HSSFSheet sheet1 = workbook.getSheetAt(0);    //得到商户基本信息工作表
            HSSFSheet sheet2 = workbook.getSheetAt(1);    //得到商户签约信息工作表
            HSSFSheet sheet3 = workbook.getSheetAt(2);    //得到商户结算信息工作表
            buffErr = bMchntBaseInfoService.analysisExcel(sheet1, sheet2, sheet3, maxRecords, dbCharsetEnum, mchntList);
//            return String.valueOf(code);
        } else if (fileName.endsWith(".xlsx")) {
            XSSFWorkbook workbook = null;
            try {
                workbook = new XSSFWorkbook(excelFile.getInputStream());    //2007版本的excel，用.xlsx结尾.得到工作簿
            } catch (Exception e) {
                log.error(e.getMessage());
            }
            Sheet sheet1 = workbook.getSheetAt(0);    //得到商户基本信息工作表
            Sheet sheet2 = workbook.getSheetAt(1);    //得到商户签约信息工作表
            Sheet sheet3 = workbook.getSheetAt(2);    //得到商户结算信息工作表

            buffErr = bMchntBaseInfoService.analysisExcel(sheet1, sheet2, sheet3, maxRecords, dbCharsetEnum, mchntList);

        } else {
            log.error("文件不是excel文件");
            throw new RedpException("文件不是excel文件");
        }
        if (Common.isNotBlank(buffErr)) {
            return OperationResult.buildFailureResult(buffErr.toString().replace("\\r\\n", "</br>"));
        } else {
            if (mchntList.size() > 0) {//提交联机批量导入
                MchntBatchImportRequest req = new MchntBatchImportRequest();
                req.setMchntInfoList(mchntList);
                req.setUserId(user.getId());
                return bMchntBaseInfoService.mchntBatchImport(instId, req, bMchntBaseInfoService.genMerOrder(user.getInstId()));
            } else {
                return OperationResult.buildFailureResult("请填写有效数据！");
            }
        }
    }


    //@RequiresPermissions("商户管理:统一支付平台商户管理")
    @RequestMapping(value = "/gridExport")
    public void gridExportAll(Model model, HttpServletRequest request, HttpServletResponse response) throws RedpException {
        String instId = request.getParameter("instId");
        String exportFlag = request.getParameter("exportFlag");
        UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);
        if (Common.isBlank(instId)) {
            if (Common.isNotBlank(user) && Common.isNotBlank(user.getInstId())) {
                instId = user.getInstId();
            }
        } else {
            //非运营中心管理员使用与自己所属法人行不符的法人行号查询数据时提示异常
            if (Common.isNotBlank(user) && Common.isNotBlank(user.getInstId())
                    && !user.isAdmin() && !instId.equals(user.getInstId())) {
                log.error("查询商户信息列表请求参数与用户身份不符");
                model.addAttribute("error", "查询商户信息列表请求参数与用户身份不符");
            }
        }

        UpmpSysParam defaultInst = upmpSysParamService.getById(UpmpConstant.DEAFULT_INST_PARAM_ID);
        UpmpSysParam dataDict = upmpSysParamService.findByPrimaryKey(instId, defaultInst.getPrimaryValue(),"599");
        String instName = dataDict.getPrimaryValue();
        List<ExportMchntInfoBean> rows = null;
        int pageIndex = 0;
        int pageSize = 2000;
        int totalPage = 0;
        try {
            //    exportDatas = hander(requestMappingVal,requestMappingHandlerMapping,  new Object[]{request,model});
            HashMap<String, Object> resultMap = bMchntBaseInfoService.exportFromBomp(request, instId, user, bMchntBaseInfoService.genMerOrder(user.getInstId()), pageIndex, pageSize);
            rows = resultMap.get("resultData") == null ? null : (List<ExportMchntInfoBean>) resultMap.get("resultData");
            totalPage = resultMap.get("totalPage") == null ? 0 : (int) resultMap.get("totalPage");
        } catch (Exception e) {
            request.getSession(false).removeAttribute(exportFlag);
            log.error("导出列表数据出现异常", e);
            throw new RedpException("导出数据出现异常"+e.getCause());
        }
        if (null == rows || rows.size() <= 0) {
            request.getSession(false).removeAttribute(exportFlag);
            log.error("没有查询到数据");
//            throw new RedpException("没有查询到数据!");
        }

        try {
            String filename = "商户信息.xlsx";
            filename = new String(filename.getBytes("GBK"), "ISO-8859-1");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + filename);
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            //    List<Map> rows = exportDatas.getContent();
            OutputStream os = response.getOutputStream();

            SXSSFWorkbook wb = new SXSSFWorkbook();//创建Excel工作簿对象
            SXSSFSheet sheet = (SXSSFSheet) wb.createSheet("商户信息");//创建Excel工作表对象

            // 创建Excel的sheet的第一行,即列头
            SXSSFRow hssfFirstRow = (SXSSFRow) sheet.createRow(0);
            for (int i = 0; i < MchntImportExportInit.mchntExportInfo.size(); i++) {
                ExcelColumnAttr colAttr = MchntImportExportInit.mchntExportInfo.get(i);
                String cell = colAttr.getColumnName();
                // 创建一个Excel的单元格
                SXSSFCell hssfCell = (SXSSFCell) hssfFirstRow.createCell(i);
                hssfCell.setCellValue(cell);
            }
            /*导出第一页之后获取总页数，之后循环导出剩余数据*/
            for (pageIndex = 0; pageIndex < totalPage; pageIndex++) {
                if (pageIndex != 0) {
                    HashMap<String, Object> resultMap = bMchntBaseInfoService.exportFromBomp(request, instId, user,  bMchntBaseInfoService.genMerOrder(user.getInstId()), pageIndex, pageSize);
                    rows = resultMap.get("resultData") == null ? null : (List<ExportMchntInfoBean>) resultMap.get("resultData");
                }
                if (rows != null) {
                    for (int i = 0; i < rows.size(); i++) {
                        Object row = rows.get(i);
                        Map rowMap = null;
                        if (!(row instanceof Map)) {
                            rowMap = new BeanMap(row);
                        } else {
                            rowMap = (Map) row;
                        }
                        if (null != rowMap && !rowMap.isEmpty()) {
                            rowMap.put("instName", instName);
                            log.trace("Row {}: {}", i, rowMap);
                            // 创建Excel的sheet的一行
                            SXSSFRow hssfRow = (SXSSFRow) sheet.createRow(pageIndex * pageSize + i + 1);
                            for (int j = 0; j < MchntImportExportInit.mchntExportInfo.size(); j++) {
                                ExcelColumnAttr colAttr = MchntImportExportInit.mchntExportInfo.get(j);
                                String cell = rowMap.get(colAttr.getColumnEname()) == null ? "" : rowMap.get(colAttr.getColumnEname()).toString();
                                if (Common.isNotBlank(colAttr.getConvertValueByEnumClazz())) {
                                    Object cellName = EnumUtils.getEnumDescriotionByValue(cell, colAttr.getConvertValueByEnumClazz(), "getType", "getDesc");
                                    if (Common.isNotBlank(cellName)) {
                                        cell += "-" + cellName.toString();
                                    }
                                }
                                // 创建一个Excel的单元格
                                SXSSFCell hssfCell = (SXSSFCell) hssfRow.createCell(j);
                                hssfCell.setCellValue(cell);
                            }
                        }
                    }
                }
            }
            wb.write(os);
            IOUtils.closeQuietly(os);
        } catch (Exception e) {
            log.error("间联商户导出异常", e);
            throw new RedpException("间联商户导出异常：" + e.getMessage());
        }
    }


    //@RequiresPermissions("商户管理:统一支付平台商户管理")
    @RequestMapping(value = "/getTemplate")
    public void getTemplate(HttpServletRequest request, HttpServletResponse response) throws RedpException, IOException {
        //  String file = "商户批量导入模板.xlsx";
        //  ExcelDownload.getExcel(request, response, file);
        String fileName = "商户批量导入模板.xls";
        String instId = request.getParameter("instId");
        ExcelOperaUtil eo = new ExcelOperaUtil();
        exportExcel(eo, fileName, instId, request, response);
    }

    @GetMapping("/openCashOut")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "mchntNo", value = "商户号", required = true, dataType = "String")
    })
    public Map<String, Object> openCashOut(UpmpBMchntBaseInfo entity) throws RedpException {
        return this.bMchntBaseInfoService.openCashOut(entity);

    }

    @PostMapping("/openCashOut")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String")
    })
    public OperationResult openCashOutSave(@Valid UpmpBMchntFeeInfo entity) throws RedpException {
        try {
            return this.bMchntBaseInfoService.openCashOutSave(entity);
        } catch (Exception e) {
            String message = "处理失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @GetMapping("/getreqD0")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "mchntNo", value = "商户号", required = true, dataType = "String")
    })
    public OperationResult getreqD0(@NotBlank(message = "{required}") String instId, @NotBlank(message = "{required}") String mchntNo) throws RedpException {

        return this.bMchntBaseInfoService.getreqD0(instId, mchntNo);

    }

    @PostMapping("/creditReport")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String")
    })
    public OperationResult creditReport(@Valid OnlineVerificationVO entity) throws RedpException {
        try {
            return this.bMchntBaseInfoService.creditReport(entity);
        } catch (Exception e) {
            String message = "处理失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @PostMapping("/onlineVerification")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String")
    })
    public OperationResult onlineVerification(@Valid OnlineVerificationVO entity) throws RedpException {
        try {
            return this.bMchntBaseInfoService.onlineVerification(entity);
        } catch (Exception e) {
            String message = "处理失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @PostMapping("/thirdEntry")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "opr", value = "商户报备类操作标识0入驻，1修改，2查询", dataType = "String")
    })
    public OperationResult thirdEntry(@Valid InstMchntRegisterVO entity, String opr) throws RedpException {
        try {
            return this.bMchntBaseInfoService.thirdEntry(entity, opr);
        } catch (Exception e) {
            String message = "处理失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }


    @PostMapping("/ocrService")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "ocrType", value = "ocr类型", required = true, dataType = "String")
    })
    public OperationResult ocrService(@Valid OcrRequest req, String instId, String elId, HttpServletRequest request) throws RedpException {
        String ocrType = req.getOcrType();
        UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);
        HttpSession session = request.getSession();
        String imageData = (String) session.getAttribute(elId + "imageData");
        if (Common.isBlank(imageData)) {
            return new OperationResult(OperationResult.OPERATION_RESULT_TYPE.failure, "识别失败");
        }
        session.removeAttribute(elId + "imageData");

        if (imageData.indexOf(",") > 0) {
            String[] imgDatas = imageData.split(",");
            req.setImageData(imgDatas[1]);
        }
        req.setOcrType(ocrType);
        req.setUserId(user.getId());
        log.info("开始ocr识别！");
        OcrResponse response = bMchntBaseInfoService.ocrService(instId, user, req, bMchntBaseInfoService.genMerOrder(user.getInstId()));
        if (Common.isNotBlank(response)) {
            if (OcrTypeEnum.BANK_CARD_IMAGE.getType().equals(ocrType)) {
                OcrCardInfoBean cardInfo = JSON.parseObject(response.getOcrResult(), OcrCardInfoBean.class);
                return OperationResult.buildSuccessResult(BompTxnNumEnum.ocrService.getDesc() + "交易成功", cardInfo);
            } else if (OcrTypeEnum.ID_IMAGE.getType().equals(ocrType)) {
                OcrIdInfoBean idInfo = JSON.parseObject(response.getOcrResult(), OcrIdInfoBean.class);
                return OperationResult.buildSuccessResult(BompTxnNumEnum.ocrService.getDesc() + "交易成功", idInfo);
            } else {
                OcrBusinessLicenseInfoBean licenseInfo = JSON.parseObject(response.getOcrResult(), OcrBusinessLicenseInfoBean.class);
                return OperationResult.buildSuccessResult(BompTxnNumEnum.ocrService.getDesc() + "交易成功", licenseInfo);
            }
        } else {
            return new OperationResult(OperationResult.OPERATION_RESULT_TYPE.failure, "识别失败");
        }
    }

    @PostMapping("/cancelQuery")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "mchntNo", value = "商户号", required = true, dataType = "String")
    })
    public OperationResult cancelQuery(@NotBlank(message = "{required}") String instId, @NotBlank(message = "{required}") String mchntNo) throws RedpException {
        try {
            return this.bMchntBaseInfoService.cancelQuery(instId, mchntNo);
        } catch (Exception e) {
            String message = "查询失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @PostMapping("/instMchntBlacklist")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "mchntName", value = "商户名称", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "mchntNo", value = "商户号", required = true, dataType = "String")
    })
    public OperationResult instMchntBlacklist(@NotBlank(message = "{required}") String instId, @NotBlank(message = "{required}") String mchntNo, @NotBlank(message = "{required}") String mchntName) throws RedpException {
        try {
            return this.bMchntBaseInfoService.instMchntBlacklist(instId, mchntNo, mchntName);
        } catch (Exception e) {
            String message = "处理失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @PostMapping("/accSign")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "acctNo", value = "账号", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "mchntNo", value = "商户号", required = true, dataType = "String")
    })
    public OperationResult accSign(@NotBlank(message = "{required}") String instId,
                                   @NotBlank(message = "{required}") String acctNo, @NotBlank(message = "{required}") String mchntNo) throws RedpException {
        try {
            return this.bMchntBaseInfoService.accSign(instId, acctNo, mchntNo);
        } catch (Exception e) {
            String message = "处理失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @PostMapping("/mchntType")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "optFlag", value = "操作符", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "mchntNo", value = "商户号", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "refuseReason", value = "拒绝原因", required = true, dataType = "String")
    })
    public OperationResult mchntType(@NotBlank(message = "{required}") String instId, @NotBlank(message = "{required}") String optFlag,
                                     @NotBlank(message = "{required}") String mchntNo, @NotBlank(message = "{required}") String refuseReason) throws RedpException {
        try {
            return this.bMchntBaseInfoService.mchntType(instId, optFlag, mchntNo, refuseReason);
        } catch (Exception e) {
            String message = "处理失败";
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    @GetMapping("/queryMchntNo")
    //    @RequiresPermissions("bMchntBaseInfo:update")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "mchntNo", value = "连锁商户号", required = true, dataType = "String")
    })
    public OperationResult queryMchntNo(@NotBlank(message = "{required}") String instId,
                                        @NotBlank(message = "{required}") String mchntNo) throws RedpException {

        UpmpBMchntBaseInfo bmchntbaseinfo = bMchntBaseInfoService.queryMchntNo(instId, mchntNo);
        if (Common.isNotBlank(bmchntbaseinfo)) {
            return OperationResult.buildSuccessResult();
        }
        return OperationResult.buildFailureResult("连锁商户不存在");

    }

    /**
     * 获取商户信息
     */
    // //@RequiresPermissions("商户管理:统一支付平台商户管理")
    @GetMapping(value = "/getcupsMchntName")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "key", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "value", value = "连锁商户号", required = true, dataType = "String")
    })
    public OperationResult getcupsMchntName(@NotBlank(message = "{required}") String key, @NotBlank(message = "{required}") String value, @NotBlank(message = "{required}") String instId) {
        String cupsMchntName = "";
        try {
            cupsMchntName = pDstChannelCfgService.cupsMchntName(key, value, instId);
        } catch (Exception e) {
            log.info("获取银联商户名称时异常:[{}]", e);
        }
        return OperationResult.buildSuccessResult(cupsMchntName);
    }

    /**
     * 筛选代理商列表数据
     *
     * @return
     */
    @GetMapping(value = "/agentMchntSelect2List")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "参数", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "agentMchntNo", value = "参数", required = true, dataType = "String")
    })
    public Map<String, Object> agentMchntSelect2List(String instId,String agentMchntNo, QueryRequest request) throws RedpException {
        return bMchntBaseInfoService.agentMchntSelect2List(instId,agentMchntNo, request);
    }

    /**
     * 行业类别列表数据
     *
     * @param request
     * @return
     */
    @GetMapping(value = "/industryTypeSelect2List")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "q", value = "参数", required = true, dataType = "String")
    })
    public Map<String, Object> industryTypeSelect2List(String q, QueryRequest request) throws RedpException {
        return bMchntBaseInfoService.industryInfoSelect2List(q, request);

    }

    /**
     * 筛选商圈列表数据
     *
     * @param request 必须包含instId
     * @return
     */
    @GetMapping(value = "/mchntAreaSelect2List")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "q", value = "参数", required = true, dataType = "String")
    })
    public Map<String, Object> mchntAreaSelect2List(String q, QueryRequest request) throws RedpException {
        return bMchntBaseInfoService.mchntAreaSelect2List(q, request);
    }

    /**
     * 筛选商户等级列表数据
     *
     * @param request 必须包含instId
     * @return
     */
    @GetMapping(value = "/mchntLevelSelect2List")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "q", value = "参数", required = true, dataType = "String")
    })
    public Map<String, Object> mchntLevelSelect2List(String q, QueryRequest request) throws RedpException {
        return bMchntBaseInfoService.mchntLevelSelect2List(q, request);
    }

    /**
     * 平台商户列表数据
     *
     * @param request 必须包含instId
     * @return
     */
    @GetMapping(value = "/platMchntSelect2List")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "q", value = "参数", required = true, dataType = "String")
    })
    public Map<String, Object> platMchntSelect2List(String q, QueryRequest request) throws RedpException {
        return bMchntBaseInfoService.platMchntSelect2List(q, request);
    }

    /**
     * 平台商户号获取平台商户信息
     *
     * @return
     */
    @GetMapping(value = "/findPlatMchntByCode")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "key", value = "机构标识", required = true, dataType = "String")
    })
    public UpmpBPlatMchntInfo findPlatMchntByCode(String platMchntNo, String instId) {
        LambdaQueryWrapper<UpmpBPlatMchntInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UpmpBPlatMchntInfo::getPlatMchntNo, platMchntNo);
        wrapper.eq(UpmpBPlatMchntInfo::getInstId, instId);
        return platMchntInfoService.getOne(wrapper);
    }

    /**
     * 进件数据统计
     *
     * @return
     */
    @GetMapping(value = "/newMchntCount")

    public Map newMchntCount(String userId) {
        return bMchntBaseInfoService.newMchntCount(userId);
    }

    /**
     * 集团商户列表数据
     *
     * @param request 必须包含instId
     * @return
     */
    @GetMapping(value = "/groupMchntSelect2List")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "q", value = "参数", required = true, dataType = "String")
    })
    public Map<String, Object> groupMchntSelect2List(String q, QueryRequest request) throws RedpException {
        return bMchntBaseInfoService.groupMchntSelect2List(q, request);
    }


    /**
     * 拓展经理列表数据
     *
     * @param request 必须包含instId
     * @return
     */
    @GetMapping(value = "/managerInfoSelect2List")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "q", value = "参数", required = true, dataType = "String")
    })
    public Map<String, Object> managerInfoSelect2List(String q, QueryRequest request) throws RedpException {
        return bMchntBaseInfoService.managerInfoSelect2List(q, request);
    }


    /**
     * 拓展经理列表数据
     *
     * @param request 必须包含instId
     * @return
     */
    @GetMapping(value = "/managerInfoList")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "managerName", value = "经理名称", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "roleType", value = "角色类型", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "signInstType", value = "拓展经理签约机构类型", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "orgCode", value = "机构代码", required = true, dataType = "String")
    })
    public Page<ManagerInfoBean> managerInfoList(QueryRequest request, String instId, String managerName, String roleType, String signInstType, String orgCode) {
        return bMchntBaseInfoService.managerInfoList(request, instId, managerName, roleType, signInstType, orgCode);
    }

    /**
     * 人行行名行号模糊查询
     *
     * @param request 必须包含instId
     * @return
     */
    @GetMapping(value = "/bankNameCodeQuerySelect2List")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "q", value = "参数", required = true, dataType = "String")
    })
    public Map<String, Object> bankNameCodeQuerySelect2List(String q, QueryRequest request) throws RedpException {
        return bMchntBaseInfoService.bankNameCodeQuerySelect2List(q, request);
    }

    /**
     * 根据商户号或商户名称筛选 正式 商户列表数据
     *
     * @param request 必须包含instId
     * @return
     */
    @GetMapping(value = "/mchntFormalSelect2List")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "q", value = "参数", required = true, dataType = "String")
    })
    public Map<String, Object> mchntFormalSelect2List(String q, QueryRequest request) throws RedpException {
        return getDataTable(bMchntBaseInfoService.mchntFormalSelect2List(q, request));
    }

    /**
     * 根据费率代码或名称筛选费率模板列表数据
     *
     * @param request 必须包含instId
     * @return
     */
    @GetMapping(value = "/feeTemplateSelect2List")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "q", value = "参数", required = true, dataType = "String")
    })
    public Map<String, Object> feeTemplateSelect2List(String q, QueryRequest request) throws RedpException {
        return bMchntBaseInfoService.feeTemplateSelect2List(q, request);
    }

    /**
     * 筛选银联商户列表数据
     *
     * @param request 必须包含instId
     * @return
     */
    @GetMapping(value = "/cupsmchntSelect2List")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "q", value = "参数", required = true, dataType = "String")
    })
    public Map<String, Object> cupsmchntSelect2List(String q, QueryRequest request) throws RedpException {
        return bMchntBaseInfoService.cupsmchntSelect2List(q, request);
    }

    /**
     * 集团商户列表数据
     *
     * @param request 必须包含instId
     * @return
     */
    @GetMapping(value = "/registerselect2")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "q", value = "参数", required = true, dataType = "String")
    })
    public Map<String, Object> registerselect2(String q, QueryRequest request) throws RedpException {
        return bMchntBaseInfoService.registerselect2(q, request);
    }


    @GetMapping(value = "/unionMerGrpSelect2List")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "q", value = "参数", required = true, dataType = "String")
    })
    public Map<String, Object> unionMerGrpSelect2List(String q, QueryRequest request) throws RedpException {
        return getDataTable(merGrpInfoService.mergrpinfoSelect2List(request, q));
    }

    @GetMapping(value = "/indusSelect2List")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "q", value = "参数", required = true, dataType = "String")
    })
    public Map<String, Object> indusSelect2List(QueryRequest request, IndustryInfo q) throws RedpException {
        return getDataTable(industryInfoService.indusSelect2List(request, q));
    }

    /**
     * 连锁商户查询
     *
     * @param request 必须包含instId
     * @return
     */
    @GetMapping(value = "/chainMchntNo")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "q", value = "参数", required = true, dataType = "String")
    })
    public Map<String, Object> chainMchntNo(QueryRequest request, @NotBlank(message = "{required}") String q) {
        return getDataTable(bMchntBaseInfoService.chainMchntNoSelect2List(request, q));
    }

    /**
     * 发起微信实名认证
     *
     * @return
     * @throws RedpException
     */
//    //@RequiresPermissions("商户管理:统一支付平台商户管理")
    @PostMapping(value = "/wxCheck")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "instId", value = "机构标识", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "realNameApplyNo", value = "实名认证申请单号", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "mchntNo", value = "商户号", required = true, dataType = "String")
    })
    public OperationResult wxCheck(String instId, String realNameApplyNo, String mchntNo) throws RedpException {
        UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);
        CommonUtils.validateUserInst(instId, user);
        Map<String, Object> result = com.google.common.collect.Maps.newHashMap();

        //不确定联机接口，先写死返回成功和返回示例值
        String qrcodeData = "cGFnZXMvYXBwbHkvYXBpdzQvd2VsY29tZS93ZWxjb21lP2FwcGx5bWVudF9pZD14eHg=";
        String base64 = new String(Base64.getDecoder().decode(qrcodeData));

        result.put("respCode", BusinessContainer.BSPS_SUCCESS);
        result.put("qrcodeData", "data:image/png;base64," + base64);
        log.info("商户编号为：" + mchntNo + "的商户，" + BompTxnNumEnum.settleAccountSign.getDesc() + "账户状态正常");
        return OperationResult.buildSuccessResult(BompTxnNumEnum.settleAccountSign.getDesc() + "交易成功", result);
//        return bMchntBaseInfoService.settleAccountSign(user,bMchntBaseInfoService.genMerOrder(user.getInstId()),bompMchntManageService,acctNo,mchntNo);
    }

    /*导出模板文件*/
    private void exportExcel(ExcelOperaUtil eo, String fileName, String instId, HttpServletRequest request, HttpServletResponse response) {
        OutputStream httpOut = null;
        try {

            /* 获取输出流 */
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            response.setDateHeader("Expires", 0L);
            String header = request.getHeader("User-Agent");
            if (header.toLowerCase().contains("firefox")) {
                BASE64Encoder base64Encoder = new BASE64Encoder();
                response.setHeader("Content-Disposition", "attachment; filename==?UTF-8?B?" + (new String(base64Encoder.encode(fileName.getBytes("UTF-8")))) + "?=");
            } else {
                response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
            }
            httpOut = response.getOutputStream();

            /* 创建excel对象 */
            HSSFWorkbook wb = new HSSFWorkbook();

            createTemplateSheet(eo, wb);

            wb.write(httpOut);
            IOUtils.closeQuietly(httpOut);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (httpOut != null) {
                try {
                    httpOut.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void createTemplateSheet(ExcelOperaUtil eo, HSSFWorkbook wb) {
        List<ImportExcelColumnAttr> mchntImportBaseInfo = MchntImportExportInitNew.mchntImportBaseInfo;
        List<ImportExcelColumnAttr> mchntImportSignInfo = MchntImportExportInitNew.mchntImportSignInfo;
        List<ImportExcelColumnAttr> mchntImportSettlInfo = MchntImportExportInitNew.mchntImportSettlInfo;
        // sheet对象
        HSSFSheet sheet = wb.createSheet("商户基本信息");
        HSSFSheet sheet1 = wb.createSheet("商户签约信息");
        HSSFSheet sheet2 = wb.createSheet("商户结算信息");
        //标题行
        HSSFRow rowTile = sheet.createRow(0);
        HSSFRow rowTile1 = sheet1.createRow(0);
        HSSFRow rowTile2 = sheet2.createRow(0);
        //单元格格式对象
        HSSFDataFormat cellFormat = wb.createDataFormat();
        //创建隐藏sheet页存储地区代码信息
        createAreaCdHideSheet(eo, wb);
        //创建隐藏sheet页存储收单机构信息
        createAcqInsCdHideSheet(eo, wb);
        //创建隐藏sheet页存储商户等级信息
        createMchntLevelHideSheet(eo, wb);
        //创建隐藏sheet页存储收商户经营类目
        createMerGrpHideSheet(eo, wb);

        createSheet(rowTile, cellFormat, eo, wb, sheet, mchntImportBaseInfo, "E", "F");
        createSheet(rowTile1, cellFormat, eo, wb, sheet1, mchntImportSignInfo, "G", "H");
        createSheet(rowTile2, cellFormat, eo, wb, sheet2, mchntImportSettlInfo, "J", "K");

    }
    String[] provinces;
    String[] acqInsCds;
    String[] mchntLevel;
    String[] mcgrp;
    public void createSheet(HSSFRow rowTile, HSSFDataFormat cellFormat, ExcelOperaUtil eo, HSSFWorkbook wb, HSSFSheet sheet, List<ImportExcelColumnAttr> importExcelColumnAttrlst, String proIdex, String cityIdex) {
        for (int colIndex = 0; colIndex < importExcelColumnAttrlst.size(); colIndex++) {
            ImportExcelColumnAttr colAttr = importExcelColumnAttrlst.get(colIndex);
            //单个列标题
            String column = colAttr.getColumnName();
            //列名称
            String key = colAttr.getColumnEname();

            sheet.setColumnWidth(colIndex, (3000));
            HSSFCell cell = rowTile.createCell(colIndex);
            cell.setCellValue(column);
            String validData = colAttr.getDataformat();
            String[] format = {};
            if (!StringUtils.isEmpty(validData))
                format = validData.split(";");
            if (format.length > 0) {
                int funNum = Integer.parseInt(format[0]);
                HSSFDataValidation validateData = null;
                switch (funNum) {
                    case 1://文本框
                        HSSFCellStyle cellStyle1 = wb.createCellStyle();
                        cellStyle1.setDataFormat(cellFormat.getFormat("@"));
                        eo.setCellType((short) 1, (short) 200, (short) colIndex, sheet, cellStyle1);
                        validateData = eo.setValidate((short) 1, (short) 200, (short) colIndex, (short) colIndex, format);
                        break;
                    case 2:    //下拉列表
                        HSSFCellStyle cellStyle2 = wb.createCellStyle();
                        cellStyle2.setDataFormat(cellFormat.getFormat("@"));
                        eo.setCellType((short) 1, (short) 200, (short) colIndex, sheet, cellStyle2);
                        String[] boxVal2 = colAttr.getBoxvalid() == null ? null : colAttr.getBoxvalid().split(";");
                        if (boxVal2 != null) {
                            String[] boxVals2 = new String[6];
                            if (!StringUtils.isEmpty(boxVal2[0])) {
                                if ("fromdb".equals(boxVal2[0])) {//下拉列表从数据库表取
                                    if ("signInstId".equals(key)) {
                                        boxVals2 = acqInsCds;
                                        validateData = eo.setCheckBoxs((short) 1, (short) 200, (short) colIndex, (short) colIndex, "signInstId!$A$2:$A$" + acqInsCds.length + 1, format[5]);
                                        break;
                                    } else if ("mchntLevel".equals(key)) {
                                        boxVals2 = mchntLevel;
                                        validateData = eo.setCheckBoxs((short) 1, (short) 200, (short) colIndex, (short) colIndex, "mchntLevel!$A$2:$A$" + mchntLevel.length + 1, format[5]);
                                        break;
                                    }
                                } else if ("special".equals(boxVal2[0])) {
                                    boxVals2 = boxVal2[1].split(",");
                                } else if ("linkage".equals(boxVal2[0])) {//实现联动
                                    if ("registerProvince".equals(key)) {
                                        boxVals2 = provinces;
                                        validateData = eo.setCheckBoxs((short) 1, (short) 200, (short) colIndex, (short) colIndex, boxVals2, format[5]);
                                    } else if ("registerCity".equals(key)) {
                                        for (int r = 1; r <= 200; r++) {
                                            validateData = eo.setCheckBoxs((short) r, (short) r, (short) colIndex, (short) colIndex, "INDIRECT($" + proIdex + "$" + (r + 1) + ")", format[5]);
                                            sheet.addValidationData(validateData);
                                        }
                                    } else if ("registerArea".equals(key)) {
                                        for (int r = 1; r <= 200; r++) {
                                            validateData = eo.setCheckBoxs((short) r, (short) r, (short) colIndex, (short) colIndex, "INDIRECT($" + cityIdex + "$" + (r + 1) + ")", format[5]);
                                            sheet.addValidationData(validateData);
                                        }
                                    } else if ("managementScope".equals(key)) {
                                        boxVals2 = mcgrp;
                                        validateData = eo.setCheckBoxs((short) 1, (short) 200, (short) colIndex, (short) colIndex, boxVals2, format[5]);
                                    } else if ("industryType".equals(key)) {
                                        for (int r = 1; r <= 200; r++) {
                                            validateData = eo.setCheckBoxs((short) r, (short) r, (short) colIndex, (short) colIndex, "INDIRECT($I$" + (r + 1) + ")", format[5]);
                                            sheet.addValidationData(validateData);
                                        }
                                    }
                                    break;
                                } else {
                                    boxVals2 = boxVal2;
                                }
                                validateData = eo.setCheckBoxs((short) 1, (short) 200, (short) colIndex, (short) colIndex, boxVals2, format[5]);
                            }
                        }
                        break;
                    case 3://数字
                        HSSFCellStyle cellStyle3 = wb.createCellStyle();
                        cellStyle3.setDataFormat(cellFormat.getFormat("@"));
                        eo.setCellType((short) 1, (short) 200, (short) colIndex, sheet, cellStyle3);
                        validateData = eo.setValidate((short) 1, (short) 200, (short) colIndex, (short) colIndex, format);
                        break;
                }
                if (validateData != null) {
                    sheet.addValidationData(validateData);
                }
            }
        }
    }

    private void createAreaCdHideSheet(ExcelOperaUtil eo, HSSFWorkbook wb) {
        List listPro = new ArrayList();
        Map<String, List<String>> siteMap = new HashMap<String, List<String>>();
        Sheet hideSheet = wb.createSheet("areacd");
        wb.setSheetHidden(wb.getSheetIndex(hideSheet), true);

        int rowId = 0;
        // 设置第一行，存省的信息
        Row proviRow = hideSheet.createRow(rowId++);
        proviRow.createCell(0).setCellValue("省列表");
        listPro = regionInfoService.provinceAreaInfoSelect();
        siteMap = regionInfoService.getAREA_CD(listPro);
        provinces = getPropertyStr(proviRow, listPro, "AREA_NAME");
        // 将具体的数据写入到每一行中，行开头为父级区域，后面是子区域。
        Iterator<String> keyIterator = siteMap.keySet().iterator();
        while (keyIterator.hasNext()) {
            String key = keyIterator.next();
            List<String> son = siteMap.get(key);

            Row row = hideSheet.createRow(rowId++);
            row.createCell(0).setCellValue(key);
            for (int i = 0; i < son.size(); i++) {
                Cell cell = row.createCell(i + 1);
                cell.setCellValue(son.get(i));
            }

            // 添加名称管理器
            String range = eo.getRange(1, rowId, son.size());
            Name name = wb.createName();
            name.setNameName(key);
            String formula = "areacd!" + range;
            name.setRefersToFormula(formula);
        }
    }

    private void createMerGrpHideSheet(ExcelOperaUtil eo, HSSFWorkbook wb) {
        List listMerGrp = new ArrayList();
        Map<String, List<String>> siteMap = new HashMap<String, List<String>>();
        Sheet hideSheet = wb.createSheet("mergrp");
        wb.setSheetHidden(wb.getSheetIndex(hideSheet), true);

        int rowId = 0;
        Row proviRow = hideSheet.createRow(rowId++);
        proviRow.createCell(0).setCellValue("商户组别列表");
        listMerGrp = merGrpInfoService.getMcGrpList(BizDataStatusEnum.STATUS_NORMAL.getType());
        siteMap = industryInfoService.getIndustryInfos(listMerGrp);
        mcgrp = getPropertyStr(proviRow, listMerGrp, "GRPDESC");
        // 将具体的数据写入到每一行中，行开头为父级区域，后面是子区域。
        Iterator<String> keyIterator = siteMap.keySet().iterator();
        while (keyIterator.hasNext()) {
            String key = keyIterator.next();
            List<String> son = siteMap.get(key);

            Row row = hideSheet.createRow(rowId++);
            row.createCell(0).setCellValue(key);
            for (int i = 0; i < son.size(); i++) {
                Cell cell = row.createCell(i + 1);
                cell.setCellValue(son.get(i));
            }

            // 添加名称管理器
            String range = eo.getRange(1, rowId, son.size());
            Name name = wb.createName();
            name.setNameName(key);
            String formula = "mergrp!" + range;
            name.setRefersToFormula(formula);
        }
    }

    private void createAcqInsCdHideSheet(ExcelOperaUtil eo, HSSFWorkbook wb) {
        Sheet hideSheet = wb.createSheet("signInstId");
        wb.setSheetHidden(wb.getSheetIndex(hideSheet), true);
        UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);
        int rowId = 0;
        Row acqInsCdRow = hideSheet.createRow(rowId++);
        acqInsCdRow.createCell(0).setCellValue("收单机构列表");
        UpmpOrganization organization = upmpOrganizationService.getOrgByCode(user.getOrgCode(), user.getInstId());
        Map map = new HashMap();
        map.put("ORG_INF", user.getOrgCode() + "-" + organization.getOrgName());
        List listAcq = new ArrayList();
        listAcq.add(map);
        acqInsCds = getPropertyStr(hideSheet, listAcq, "ORG_INF");
    }

    private void createMchntLevelHideSheet(ExcelOperaUtil eo, HSSFWorkbook wb) {
        UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);
        Sheet hideSheet = wb.createSheet("mchntLevel");
        wb.setSheetHidden(wb.getSheetIndex(hideSheet), true);
        int rowId = 0;
        Row acqInsCdRow = hideSheet.createRow(rowId++);
        acqInsCdRow.createCell(0).setCellValue("商户等级列表");

        List listLevel = mchntLevelInfoService.getMerLevelInfos(user.getInstId());
        mchntLevel = getPropertyStr(hideSheet, listLevel, "MCHNTLEVEL_INF");
    }

    private String[] getPropertyStr(Row proviRow, List list, String key) {
        String[] properties = new String[list.size()];
        for (int i = 0; i < list.size(); i++) {
            Map mapPro = (Map) list.get(i);
            String areaInfPro = (String) mapPro.get(key);
            properties[i] = areaInfPro;
            Cell proviCell = proviRow.createCell(i + 1);
            proviCell.setCellValue(areaInfPro);
        }
        return properties;
    }

    private String[] getPropertyStr(Sheet hiddenSheet, List list, String key) {
        String[] properties = new String[list.size()];
        for (int i = 0; i < list.size(); i++) {
            Map mapPro = (Map) list.get(i);
            String areaInfPro = (String) mapPro.get(key);
            properties[i] = areaInfPro;
            Row row = hiddenSheet.createRow(i + 1);
            Cell proviCell = row.createCell(0);
            proviCell.setCellValue(areaInfPro);
        }
        return properties;
    }
}
